package top.hmtools.jsCss.jsManager;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import top.hmtools.jsCss.autoConfiguration.JsCssAutoConfiguration;
import top.hmtools.jsCss.common.BaseController;
import top.hmtools.jsCss.common.ResourcesBean;
import top.hmtools.jsCss.yui.JsCompressorComponet;

/**
 * javascript相关操作的controller
 * @author HyboJ
 * 创建日期：2017-9-26下午10:33:07
 */
@Controller
//@ConditionalOnBean(value=IsEnableJsCss.class)
public class JavascriptController extends BaseController{
	
	private final Logger logger = LoggerFactory.getLogger(JavascriptController.class);
	
	@Autowired
	private IJavascriptManager javascriptManager;
	
	@Autowired
	private JsCssAutoConfiguration jsCssAutoConfiguration;
	
	@Autowired
	private JsCompressorComponet jsCompressor;
	
	/**
	 * 使用yui进行压缩后的js合并内容
	 * @param jsNames
	 * @param charset
	 * @param linebreak
	 * @param munge
	 * @param preserveAllSemiColons
	 * @param disableOptimizations
	 */
	@RequestMapping(value="#{'${"+JsCssAutoConfiguration.yui_js_uri+":}'?:'/yui/js'}/{jsNames}",method={RequestMethod.GET,RequestMethod.POST})
	public void getYuiCompressJS(
			@PathVariable("jsNames")String jsNames,
			@RequestParam(defaultValue="UTF-8",name="charset",required=false) String charset,
			@RequestParam(defaultValue="-1",name="linebreak",required=false) Integer linebreak,
			@RequestParam(defaultValue="false",name="munge",required=false) Boolean munge,
			@RequestParam(defaultValue="false",name="preserveAllSemiColons",required=false) Boolean preserveAllSemiColons,
			@RequestParam(defaultValue="false",name="disableOptimizations",required=false) Boolean disableOptimizations
			){
		PrintWriter writer = null;
		HttpServletResponse response = this.getResponse();
		try {
			String jsContent = this.javascriptManager.getJs(jsNames);
			boolean verbose = this.logger.isWarnEnabled();
			// FIXME 目前已知 yuicompress 对utf-8含有bom头的内容会转换异常
			String jsYuiContent = this.jsCompressor.compressor(jsContent, linebreak, munge, verbose, preserveAllSemiColons, disableOptimizations, charset);
			
			response.reset();
			response.setBufferSize(2048);
			response.setCharacterEncoding(charset);
			response.setContentLength(jsYuiContent.getBytes(charset).length);
			response.setContentType("application/javascript");
			response.setStatus(HttpServletResponse.SC_OK);
			writer = response.getWriter();
			writer.print(jsYuiContent);
			writer.flush();
		} catch (Exception e) {
			this.logger.error("获取yui压缩后的js文件失败："+e.getMessage(),e);
			try {
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
			} catch (IOException e1) {
				this.logger.error(e1.getMessage(),e1);
			}
		}finally{
			
		}
	}
	
	/**
	 * 获取合并的javascript文件内容
	 * @param request
	 * @param response
	 */
	@RequestMapping(value="#{'${"+JsCssAutoConfiguration.js_uri+":}'?:'/js'}/{jsNames}",method={RequestMethod.GET,RequestMethod.POST})
	public void getJS(@PathVariable("jsNames")String jsNames){
		this.getJS(jsNames, "UTF-8");
	}

	/**
	 * 获取合并的javascript文件内容
	 * @param request
	 * @param response
	 */
	@RequestMapping(value="#{'${"+JsCssAutoConfiguration.js_uri+":}'?:'/js'}/encoding/{encoding}/{jsNames}",method={RequestMethod.GET,RequestMethod.POST})
	public void getJS(@PathVariable("jsNames")String jsNames,@PathVariable("encoding")String encoding){
		PrintWriter writer = null;
		HttpServletResponse response = this.getResponse();
		try {
			String jsContent = this.javascriptManager.getJs(jsNames);
			
			response.reset();
			response.setBufferSize(2048);
			response.setCharacterEncoding(encoding);
			response.setContentLength(jsContent.getBytes(encoding).length);
			response.setContentType("application/javascript");
			response.setStatus(HttpServletResponse.SC_OK);
			writer = response.getWriter();
			writer.print(jsContent);
			writer.flush();
		} catch (Exception e) {
			this.logger.error("获取js文件失败："+e.getMessage(),e);
			try {
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
			} catch (IOException e1) {
				this.logger.error(e1.getMessage(),e1);
			}
		}finally{
			if(writer != null){
//				writer.close();
			}
		}
	}
	
	/**
	 * 刷新javascript缓存库
	 * @param request
	 * @param response
	 */
	@RequestMapping(value="#{'${"+JsCssAutoConfiguration.refresh_js_uri+":}'?:'/refresh/js'}",method={RequestMethod.GET,RequestMethod.POST})
	public void refreshJS(){
		PrintWriter writer = null;
		HttpServletResponse response = this.getResponse();
		try {
			boolean refresh = this.javascriptManager.refresh();
			
			response.reset();
			response.setBufferSize(2048);
			response.setCharacterEncoding(this.jsCssAutoConfiguration.getEncoding());
			response.setContentType("text/html");
			response.setStatus(HttpServletResponse.SC_OK);
			writer = response.getWriter();
			writer.println("refresh javascript repertory status is "+refresh);
			writer.println("<br>3秒后自动跳转到JS列表页面……");
			writer.printf("<br><a href=\"%1$s\">%2$s</a>",this.jsCssAutoConfiguration.getListJsUri(),"手动跳转  "+this.jsCssAutoConfiguration.getListJsUri());
			response.setHeader("refresh","3;URL="+this.jsCssAutoConfiguration.getListJsUri()+"");
			writer.flush();
		} catch (Exception e) {
			this.logger.error("刷新js缓存失败："+e.getMessage(),e);
			try {
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
			} catch (IOException e1) {
				this.logger.error(e1.getMessage(),e1);
			}
		}finally{
			if(writer != null){
//				writer.close();
			}
		}
	}
	
	/**
	 * 获取所有javascript缓存库中js文件名
	 * @param request
	 * @param response
	 */
	@RequestMapping(value="#{'${"+JsCssAutoConfiguration.list_js_uri+":}'?:'/list/js'}",method={RequestMethod.GET,RequestMethod.POST})
	public void listJsMenu(){
		PrintWriter writer = null;
		HttpServletResponse response = this.getResponse();
		try {
			List<ResourcesBean> listResourcesBeans = this.javascriptManager.listResourcesBeans();
			
			response.reset();
			response.setBufferSize(2048);
			response.setCharacterEncoding(this.jsCssAutoConfiguration.getEncoding());
//			response.setContentLength(jsContent.length());
			response.setContentType("text/html");
			response.setStatus(HttpServletResponse.SC_OK);
			writer = response.getWriter();
			writer.println("<title>JavaScript文件列表（总计："+listResourcesBeans.size()+"条）</title>");
			writer.println("<style type=\"text/css\">a:link,a:visited{text-decoration:none;}tr:nth-child(2n){background-color: #E0FFFF;}tr:nth-child(2n+1){background-color:#FFFFFF;}</style>");
			writer.println("<h4>All javascript file name is (counts:"+listResourcesBeans.size()+"):</h4>");
			writer.println("<a href=\""+this.jsCssAutoConfiguration.getRefreshJsUri()+"\"><h4>Refresh js store</h4></a>");
			writer.println("<table>");
			for(ResourcesBean jsTmp:listResourcesBeans){
				writer.println("<tr>");
				writer.printf("<td><a href=\"%1$s\">%2$s</a></td>",this.jsCssAutoConfiguration.getJsUri()+"/"+jsTmp.getKeyName(),jsTmp.getFileFullName());
				writer.printf("<td>&nbsp;&nbsp;<a href=\"%1$s\">%2$s</a></td>",this.jsCssAutoConfiguration.getJsUri()+"/"+jsTmp.getKeyName(),jsTmp.getFileRelativePath());
				writer.printf("<td>&nbsp;&nbsp;<a href=\"%1$s\">%2$s</a></td>",this.jsCssAutoConfiguration.getJsUri()+"/encoding/UTF-8/"+jsTmp.getKeyName(),"UTF-8");
				writer.printf("<td>&nbsp;&nbsp;<a href=\"%1$s\">%2$s</a></td>",this.jsCssAutoConfiguration.getJsUri()+"/encoding/GBK/"+jsTmp.getKeyName(),"GBK");
				writer.printf("<td>&nbsp;&nbsp;<a href=\"%1$s\">%2$s</a></td>",this.jsCssAutoConfiguration.getYuiJsUri()+"/"+jsTmp.getKeyName(),"yui压缩后");
				writer.println("</tr>");
				writer.flush();
			}
			writer.println("</table>");
		} catch (Exception e) {
			this.logger.error("获取js列表失败："+e.getMessage(),e);
			try {
				response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,e.getMessage());
			} catch (IOException e1) {
				this.logger.error(e1.getMessage(),e1);
			}
		}finally{
			if(writer != null){
//				writer.close();
			}
		}
	}
}
